package rgr;

import process.Dispatcher;
import queues.QueueForTransactions;
import queues.Store;
import qusystem.MultiActor;
import stat.DiscretHisto;
//Клас моделі
public class Model {
	//Посилання на диспетчера
	private Dispatcher dispatcher;
	//Посилання на візуальну частину
	private GUI gui;
	//Дробарка
	private Drob drob;
	//Екскалатор
	private Ecsc ecsc;
	//Самосид (оригінал для MultiActor)
	private Lorry lorry; 
	//Бригада самоскидів
	private MultiActor multiLorry; 
	//Купа каміння
	private Store heep; 
	//Черга самоскидів до екскалатора
	private QueueForTransactions queueToEcsc; 
	//Черга для самоскидів у дорозі
	private QueueForTransactions queueLorryOnRoad; 
	//Гістограма для довжини черги до навантажувача
	private DiscretHisto histoForQueueToEcsc; 
	
	// ////////////////////////////////////////
	// Єдиний спосіб створити модель, це викликати цей конструктор
	// Він гарантовано передає посилання на диспетчера та GUI
	// ////////////////////////////////////////

	public Model(Dispatcher d, GUI g) {
		if (d == null || g == null) {
			System.out.println("Не визначено диспетчера або GUI для RgrModel");
			System.out.println("Подальша робота неможлива");
			System.exit(0);
		}
		dispatcher = d;
		gui = g;
		//Передаємо акторів до стартового списку диспетчера
		componentsToStartList();
	}

	private void componentsToStartList() {
		// Передаємо акторів диспетчеру
		dispatcher.addStartingActor(getDrob());
		dispatcher.addStartingActor(getEcsc());
		dispatcher.addStartingActor(getMultiLorry());
	}

	// ////////////////////////////////////////
	// Методи відкладеного створення акторів моделі,
	// ////////////////////////////////////////

	public Drob getDrob() {
		if (drob == null) {
			drob = new Drob("Дробарка", gui, this);
		}
		return drob;
	}

	public Ecsc getEcsc() {
		if (ecsc == null)
			ecsc = new Ecsc("Екскалатор", gui, this);
		return ecsc;
	}

	public MultiActor getMultiLorry() {
		if (multiLorry == null) {
			multiLorry = new MultiActor();
			multiLorry.setNameForProtocol("MultiActor для бригади самоскидів");
			multiLorry.setOriginal(getLorry());
			multiLorry.setNumberOfClones(gui.getChooseDataNLorry().getInt());
		}
		return multiLorry;
	}

	private Lorry getLorry() {
		if (lorry == null)
			lorry = new Lorry("Самоскид", gui, this);
		return lorry;
	}

	// ////////////////////////////////////////
	// Методи відкладеного створення черг
	// ////////////////////////////////////////

	public Store getHeep() {
		if (heep == null) {
			heep = new Store();
			heep.setNameForProtocol("Купа каміння");
			heep.setDispatcher(dispatcher);
		}
		return heep;
	}

	public QueueForTransactions getQueueToEcsc() {
		if (queueToEcsc == null) {
			queueToEcsc = new QueueForTransactions();
			queueToEcsc.setNameForProtocol("Черга до екскалатора");
			queueToEcsc.setDispatcher(dispatcher);
			queueToEcsc.setDiscretHisto(getHistoForQueueToEcsc());
		}
		return queueToEcsc;
	}

	public QueueForTransactions getQueueLorryOnRoad() {
		if (queueLorryOnRoad == null) {
			queueLorryOnRoad = new QueueForTransactions();
			queueLorryOnRoad.setNameForProtocol("Cамоскиди, що у дорозі");
			queueLorryOnRoad.setDispatcher(dispatcher);
		}
		return queueLorryOnRoad;
	}

	// //////////////////////////////////////////////////////
	// Методи відкладеного створення накопичувачів статистики
	// //////////////////////////////////////////////////////
	//Гістограма для довжини черги до екскалатора
	public DiscretHisto getHistoForQueueToEcsc() {
		if (histoForQueueToEcsc == null) {
			histoForQueueToEcsc = new DiscretHisto();
			histoForQueueToEcsc.init();
		}
		return histoForQueueToEcsc;
	}

	// ///////////////////////////////////////////////////////////
	// Методи ініціалізації моделі
	// //////////////////////////////////////////////////////////////
	
	//Ініціалізація для режиму "Тест"
	public void initForTest() {
		// Передаємо чергам painter-ів для динамічної індикації
		getHeep().setPainter(gui.getDiagramHeepSize().getPainter());
		getQueueToEcsc().setPainter(
				gui.getDiagramQueueToEcsc().getPainter());
		getQueueLorryOnRoad().setPainter(
				gui.getDiagramLorryOnRoad().getPainter());
	}

	//Ініціалізація для режиму "Статистика"
	public void initForStat() {
		// Не виводити протокол на консоль
		dispatcher.setProtocolFileName("");
	}

}
